package com.isoft.airportsystem.service.validation;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.isoft.airportsystem.exception.BusinessException;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.Map;
import java.util.Set;

@Service
public class ChangeDataValidator {

    private static final Set<String> VALID_CHANGE_TYPES =
            Set.of("DELAY", "CANCEL", "DIVERT", "GATE_CHANGE", "TIME_ADJUSTMENT", "AIRCRAFT_CHANGE");

    private final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
    private final ObjectMapper objectMapper;

    public ChangeDataValidator(ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
    }

    // 添加变更数据验证方法
    public Map<String, Object> validateAndParseChangeData(String changeType, String changeData) {
        // 验证变更类型有效性
        if (!VALID_CHANGE_TYPES.contains(changeType)) {
            throw new BusinessException("未知的变更类型: " + changeType);
        }

        try {
            Map<String, Object> dataMap = objectMapper.readValue(changeData, Map.class);

            switch (changeType) {
                case "DELAY":
                    validateDelayData(dataMap);
                    break;
                case "CANCEL":
                    validateCancelData(dataMap);
                    break;
                case "DIVERT":
                    validateDivertData(dataMap);
                    break;
                case "GATE_CHANGE":
                    validateGateChangeData(dataMap);
                    break;
                case "TIME_ADJUSTMENT":
                    validateTimeAdjustmentData(dataMap);
                    break;
                case "AIRCRAFT_CHANGE":
                    validateAircraftChangeData(dataMap);
                    break;
                default:
                    throw new BusinessException("未知的变更类型: " + changeType);
            }

            return dataMap;
        } catch (JsonProcessingException e) {
            throw new BusinessException("变更数据格式错误: " + changeData);
        }
    }

    // 添加延误变更验证方法
    private void validateDelayData(Map<String, Object> dataMap) {
        requireField(dataMap, "newTime", "延误变更必须包含新时间");
        requireField(dataMap, "reason", "延误变更必须包含原因");
        validateTimeFormat(dataMap.get("newTime").toString());
    }

    // 添加取消变更验证方法
    private void validateCancelData(Map<String, Object> dataMap) {
        requireField(dataMap, "reason", "取消变更必须包含原因");
    }

    // 添加备降变更验证方法
    private void validateDivertData(Map<String, Object> dataMap) {
        requireField(dataMap, "newDestination", "备降变更必须包含新目的地");
        requireField(dataMap, "reason", "备降变更必须包含原因");
    }

    // 添加登机口变更验证方法
    private void validateGateChangeData(Map<String, Object> dataMap) {
        requireField(dataMap, "newGate", "登机口变更必须包含新登机口");
        requireField(dataMap, "reason", "登机口变更必须包含原因");
    }

    // 添加时间调整验证方法
    private void validateTimeAdjustmentData(Map<String, Object> dataMap) {
        requireField(dataMap, "newDepartureTime", "时间调整必须包含新出发时间");
        requireField(dataMap, "newArrivalTime", "时间调整必须包含新到达时间");
        requireField(dataMap, "reason", "时间调整必须包含原因");

        validateTimeFormat(dataMap.get("newDepartureTime").toString());
        validateTimeFormat(dataMap.get("newArrivalTime").toString());
    }

    // 添加飞机变更验证方法
    private void validateAircraftChangeData(Map<String, Object> dataMap) {
        requireField(dataMap, "newAircraftType", "飞机变更必须包含新机型");
        requireField(dataMap, "reason", "飞机变更必须包含原因");
    }

    // 检查必填字段
    private void requireField(Map<String, Object> dataMap, String field, String errorMessage) {
        if (!dataMap.containsKey(field) || dataMap.get(field) == null ||
                dataMap.get(field).toString().trim().isEmpty()) {
            throw new BusinessException(errorMessage);
        }
    }

    private void validateTimeFormat(String time) {
        try {
            LocalDateTime.parse(time, formatter);
        } catch (DateTimeParseException e) {
            throw new BusinessException("时间格式错误: " + time + "，应为 yyyy-MM-dd HH:mm");
        }
    }
}